package com.yshy.moviechoseseatingouterapi.service.impl;

import cn.jhsjgo.commonmodel.config.request.RequestReqId;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yshy.moviechoseseatingcommon.entity.TOrder;
import com.yshy.moviechoseseatingcommon.entity.bo.orders.NoticeBo;
import com.yshy.moviechoseseatingcommon.entity.dto.NoticeDto;
import com.yshy.moviechoseseatingcommon.entity.vo.orders.NoticeCallbackBo;
import com.yshy.moviechoseseatingcommon.enums.OrderStateEnum;
import com.yshy.moviechoseseatingcommon.properties.DockingInterfaceProperties;
import com.yshy.moviechoseseatingcommon.properties.NoticeProperties;
import com.yshy.moviechoseseatingcommon.util.RequstUtil;
import com.yshy.moviechoseseatingouterapi.service.OrdersService;
import com.yshy.moviechoseseatingouterapi.service.TOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * @author :
 * @desc :
 * @create: 上午10:08
 **/
@Slf4j
@Service
public class OrdersServiceImpl implements OrdersService {
    @Autowired
    RequstUtil requstUtil;
    @Autowired
    TOrderService tOrderService;
    @Autowired
    DockingInterfaceProperties dockingInterfaceProperties;
    @Autowired
    NoticeProperties noticeProperties;

    @Override
    public String notice(NoticeBo bo) throws NoSuchAlgorithmException {
        if (!bo.getPlatformId().equals(dockingInterfaceProperties.getPlatformId())) {
            log.info("上游通知,平台id不匹配，请求id={}，请求参数={}", RequestReqId.getReqId(), JSONObject.toJSONString(bo));
            return "平台id不匹配";
        }
        NoticeDto noticeDto = new NoticeDto();
        noticeDto.setOrderNo(bo.getOrderNo());
        noticeDto.setEventType(bo.getEventType());
        noticeDto.setPlatform(bo.getPlatform());
        noticeDto.setPlatformId(bo.getPlatformId());
        String params = JSONObject.toJSONString(noticeDto);
        String paramStr = sortJsonKeys(params) + dockingInterfaceProperties.getSecret();
        String sign = RequstUtil.md5(paramStr);
        if (!sign.equalsIgnoreCase(bo.getSign())) {
            log.info("上游通知,签名不匹配，请求id={}，请求参数={}", RequestReqId.getReqId(), JSONObject.toJSONString(bo));
            return "签名不匹配";
        }
        boolean update = tOrderService.update(new LambdaUpdateWrapper<TOrder>()
                .eq(TOrder::getOrderIdDown, bo.getOrderNo())
                .ne(TOrder::getOrderState, OrderStateEnum.CANCELED.getValue())
                .ne(TOrder::getOrderState, OrderStateEnum.TRANSACTION_SUCCESS.getValue())
                .set(TOrder::getOrderState, bo.getEventType()));
        NoticeCallbackBo noticeCallbackBo = new NoticeCallbackBo();
        noticeCallbackBo.setEventType(bo.getEventType());
        noticeCallbackBo.setTimestamp(new Date().getTime() / 1000);
        NoticeCallbackBo.DataDTO dataDTO = new NoticeCallbackBo.DataDTO();
        TOrder one = tOrderService.getOne(new LambdaQueryWrapper<TOrder>().eq(TOrder::getOrderIdDown, bo.getOrderNo()));
        if (update) {
            log.info("上游通知,订单表更新成功，请求id={}", RequestReqId.getReqId());

            noticeCallbackBo.setOrderNo(one.getOrderId().toString());
            noticeCallbackBo.setDownOderNo(one.getOrderIdDown());

            if (bo.getEventType().equals(OrderStateEnum.CANCELED.getValue())) {
                dataDTO.setCancelReason(bo.getData().getCancelReason());
                noticeCallbackBo.setData(dataDTO);
                String callback = requstUtil.notice(noticeCallbackBo);
                if (callback.equals("success")) {
                    log.info("通知回调，请求id={}，请求地址={}，请求参数={}，响应参数={}", RequestReqId.getReqId(), noticeProperties.getUrl(), JSONObject.toJSONString(noticeCallbackBo), callback);
                } else {
                    log.info("通知回调，请求id={}，请求地址={}，请求参数={}，响应参数={}", RequestReqId.getReqId(), noticeProperties.getUrl(), JSONObject.toJSONString(noticeCallbackBo), callback);
                }
                return "success";
            } else {
                dataDTO.setCancelReason(null);
                noticeCallbackBo.setData(dataDTO);
                String callback = requstUtil.notice(noticeCallbackBo);
                if (callback.equals("success")) {
                    log.info("通知回调，请求id={}，请求地址={}，请求参数={}，响应参数={}", RequestReqId.getReqId(), noticeProperties.getUrl(), JSONObject.toJSONString(noticeCallbackBo), callback);
                } else {
                    log.info("通知回调，请求id={}，请求地址={}，请求参数={}，响应参数={}", RequestReqId.getReqId(), noticeProperties.getUrl(), JSONObject.toJSONString(noticeCallbackBo), callback);
                }
                return "success";
            }
        } else {
            return "fail";
        }
    }

    /**
     * 解析和排序 JSON 对象，并将排序后的键值对以 & 分隔
     *
     * @param params
     * @return
     */
    public static String sortJsonKeys(String params) {
        // 解析 JSON 字符串
        JSONObject jsonObject = JSON.parseObject(params);

        // 提取键值对并排序
        List<Map.Entry<String, Object>> entries = new ArrayList<>();
        Set<Map.Entry<String, Object>> entrySet = jsonObject.entrySet();
        for (Map.Entry<String, Object> entry : entrySet) {
            entries.add(entry);
        }

        // 排序
        Collections.sort(entries, new Comparator<Map.Entry<String, Object>>() {
            @Override
            public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
                return o1.getKey().compareTo(o2.getKey());
            }
        });

        // 构建新的字符串
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < entries.size(); i++) {
            Map.Entry<String, Object> entry = entries.get(i);
            result.append(entry.getKey()).append("=").append(entry.getValue());
            if (i < entries.size() - 1) {
                result.append("&");
            }
        }

        return result.toString();
    }

//    /**
//     * 将字符串进行MD5加密
//     *
//     * @param content 要加密的内容
//     * @return 加密后的内容
//     * @throws NoSuchAlgorithmException
//     */
//    public static String md5(String content) throws NoSuchAlgorithmException {
//        MessageDigest md = MessageDigest.getInstance("MD5");
//        md.update(content.getBytes(Charset.forName("utf-8")));
//        byte[] digest = md.digest();
//        return DatatypeConverter.printHexBinary(digest);
//    }
}
